package com.winit.openapi.interceptor.validator;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.winit.erp.spi.bpartner.BpartnerService;
import com.winit.erp.spi.user.UserService;
import com.winit.openapi.apiadapter.adapter.UmsUserServiceAdapter;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.util.Config;
import com.winit.openapi.util.RequestUtil;
import com.winit.openapi.util.SignUtil;
import com.winit.openapi.util.ValidateUtil;

public abstract class AbstractAPIRequestHandler<T extends HttpServletRequest> implements APIRequestAuthValidator<T>, APIRequestDataValidator<T> {

    private static final Logger   logger        = LoggerFactory.getLogger(AbstractAPIRequestHandler.class);

    protected static final String SIGN_INTERNAL = "00000000000000000000000000000000";

    @Resource
    private Config                config;
    @Resource
    private UserService           userService;
    @Resource
    private BpartnerService       bpartnerService;
    @Resource
    private UmsUserServiceAdapter umsUserServiceAdapter;

    private boolean checkSignFlag() {

        return config.isSignFlag();
    }

    public void checkSign(HttpServletRequest request, String token, String sign) {
        // 开关打开，32个0和按正常签名验证通过的才能正常访问API
        boolean noCheckSign = false;
        if (checkSignFlag() && SIGN_INTERNAL.equals(sign)) {
            noCheckSign = true;
        }
        // 其他情况走正常签名流程
        if (!noCheckSign && !SignUtil.checkSign(request, token, sign)) {
            logger.warn("签名校验失败：" + sign);
            String errorCode = ErrorCode.API_AUTH_TOKEN_FIALD;
            String characterEncoding = request.getCharacterEncoding();
            //如果characterEncoding为空或不是UTF-8，则提示编码错误，否则提示token异常
            if (StringUtils.isEmpty(characterEncoding) || !"UTF-8".equalsIgnoreCase(characterEncoding)) {
                errorCode = ErrorCode.API_AUTH_CHARSET_FAILED;
            }
            throw new ApiException(errorCode);
        }
    }

    public JSONObject checkBaseData(T request) throws ApiException {
        RequestMsg requestMsg = RequestUtil.getRequestMsg(request);
        if (request == null) {
            return null;
        }
        // 处理fastjson库BUG，当业务字段某个属性为null时，报net.sf.json.JSONException: null
        // object
        JSONObject json = null;
        try {
            json = (JSONObject) JSONObject.toJSON(requestMsg);
        } catch (Exception e) {
            String jsonString = JSON.toJSONString(requestMsg);
            json = JSONObject.parseObject(jsonString);
        }
        // action
        ValidateUtil.validNotNull(json, "action");
        ValidateUtil.validMaxLength(json, "action", 50);
        // timestamp
        ValidateUtil.validMaxLength(json, "timestamp", 20);

        // version
        ValidateUtil.validMaxLength(json, "version", 10);

        // sign_method
        ValidateUtil.validMaxLength(json, "sign_method", 10);

        // format
        ValidateUtil.validMaxLength(json, "format", 10);

        // platform
        ValidateUtil.validMaxLength(json, "platform", 50);

        // language
        ValidateUtil.validMaxLength(json, "language", 10);

        return json;

    }

}
